package com.hama.iotrust.common.mvc;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;

import com.hama.iotrust.common.mvc.AnnotationHandlerMethodExceptionResolver;
import com.hama.iotrust.common.util.StrUtil;

/**
 * 不必在Controller中对异常进行处理，抛出即可，由此异常解析器统一控制。<br>
 * ajax请求（有@ResponseBody的Controller）发生错误，输出JSON。<br>
 * 页面请求（无@ResponseBody的Controller）发生错误，输出错误页面。<br>
 * 
 * @author Jinjq
 */
public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {

    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(AnnotationHandlerMethodExceptionResolver.class);

    private String              defaultErrorView;

    public String getDefaultErrorView() {
        return defaultErrorView;
    }

    public void setDefaultErrorView(String defaultErrorView) {
        this.defaultErrorView = defaultErrorView;
    }

    protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response,
                                                           HandlerMethod handlerMethod, Exception exception) {

        if (handlerMethod == null) {
            return null;
        }

        Method method = handlerMethod.getMethod();

        if (method == null) {
            return null;
        }
        logger.error(exception.getMessage(), exception);

        ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);

        ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);
        if ((responseBodyAnn != null)) {
            try {
                String contentType = "application/json";
                response.setContentType(contentType);
                response.setCharacterEncoding("UTF-8");
                Map<String, Object> jsonMap = new HashMap<String, Object>();
                jsonMap.put("result", 0);
                jsonMap.put("message", exception.getMessage());
                String json = StrUtil.jsonFromObject(jsonMap);
                response.getWriter().print(json);
                response.getWriter().flush();
                response.getWriter().close();
            } catch (Exception e) {

            }
            return null;
        } else {
            if (returnValue == null) returnValue = new ModelAndView();

            returnValue.addObject("exception", exception.getMessage());
            returnValue.setViewName(defaultErrorView);
            return returnValue;
        }
    }

}
